#include <convert_manager.h>
#include <stdio.h>
#include <linux/videodev2.h>  
#include <stdint.h>
#include <string.h>


int Rgb2Rgb_isSupport(int InputPixelFormat, int OutputPixelFormat)
{
    if (iPixelFormatIn != V4L2_PIX_FMT_RGB565)
        return 0;
    if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32))
    {
        return 0;
    }
    return 1;
}


int Rgb2Rgb_Convert(PT_VideoBuff InputBuff, PT_VideoBuff OutputBuff)
{
    PT_PixelDatas ptPixelDatasIn  = &InputBuff->tPixelDatas;
    PT_PixelDatas ptPixelDatasOut = &OutputBuff->tPixelDatas;

    ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;
    ptPixelDatasOut->iWidth = ptPixelDatasIn->iWidth;

    // 如果输入不是V4L2_PIX_FMT_RGB565格式的，这个函数不支持
    if (ptPixelDatasIn != V4L2_PIX_FMT_RGB565)
    {
        printf("Do not support this input format.\n");
        return -1;
    }

    // 如果是要转化成V4L2_PIX_FMT_RGB565格式的（说明不需要进行格式转换，直接拷贝数据即可）
    if (ptPixelDatasOut->iPixelFormat == V4L2_PIX_FMT_RGB565)
    {
        ptPixelDatasOut->iBpp = 16;
        ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;
        ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;
        // 分配缓冲区
        if (!ptPixelDatasOut->aucPixelDatas)
        {
            ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);
        }
        // 拷贝数据
        memcpy(ptPixelDatasOut->aucPixelDatas, ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->iTotalBytes);
    }

    // 如果是要转化成V4L2_PIX_FMT_RGB32格式的
    else if (ptPixelDatasOut->iPixelFormat == V4L2_PIX_FMT_RGB32)
    {
        ptPixelDatasOut->iBpp = 32;
        ptPixelDatasOut->iLineBytes = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;
        ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;
        // 分配缓冲区
        if (!ptPixelDatasOut->aucPixelDatas)
        {
            ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);
        }

        // 输入缓冲区（RGB565）和输出缓冲区（RGB32）的指针
        unsigned short *src = (unsigned short *)ptPixelDatasIn->aucPixelDatas;  // RGB565 是 16 位/像素
        unsigned int *dest = (unsigned int *)ptPixelDatasOut->aucPixelDatas;   // RGB32 是 32 位/像素

        // 对于缓冲区中的每一个像素数据
        for (int i = 0; i < ptPixelDatasIn->iWidth * ptPixelDatasIn->iHeight; i++)
        {
            unsigned short rgb565 = src[i];
            
            // 提取RGB分量
            unsigned char r = (rgb565 >> 11) & 0x1F;  // 高 5 位是 R
            unsigned char g = (rgb565 >> 5)  & 0x3F;  // 中间 6 位是 G
            unsigned char b = rgb565         & 0x1F;  // 低 5 位是 B

            // 扩展到 8 位（5→8位：左移3位；6→8位：左移2位）
            r = (r << 3) | (r >> 2);  // 5→8位：r * 255 / 31 ≈ (r << 3) | (r >> 2)
            g = (g << 2) | (g >> 4);  // 6→8位：g * 255 / 63 ≈ (g << 2) | (g >> 4)
            b = (b << 3) | (b >> 2);  // 5→8位：b * 255 / 31 ≈ (b << 3) | (b >> 2)

            // 组合成 ARGB8888（A=0xFF，R、G、B）
            dest[i] = (0xFF << 24) | (r << 16) | (g << 8) | b;
        }
    }
    return 0;
}


int Rgb2Rgb_ConvertExit(PT_VideoBuff outputBuff)
{
    if (outputBuff == NULL) {
        return -1; // 错误：传入空指针
    }

    // 释放RGB数据缓冲区（如果已分配）
    if (outputBuff->tPixelDatas.aucPixelDatas != NULL) 
    {
        free(outputBuff->tPixelDatas.aucPixelDatas);
        outputBuff->tPixelDatas.aucPixelDatas = NULL; // 避免悬空指针（内存被释放但指针仍然指向原地址）
    }
    return 0; // 成功释放
}



static T_ConvertOpr g_tRgb2Rgb = {
    .name = "Rgb2Rgb",
    .isSupport = Rgb2Rgb_isSupport,
    .Convert = Rgb2Rgb_Convert,
    .ConvertExit = Rgb2Rgb_ConvertExit,
};


void RegisterRgb2Rgb(void)
{
    RegisterConvertOpr(&g_tRgb2Rgb);
}